package com.summer.boss.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.summer.boss.convert.MenuConvert;
import com.summer.boss.enums.MenuTypeEnum;
import com.summer.boss.model.vo.MenuTreeVO;
import com.summer.boss.service.ISysMenuService;
import com.summer.boss.orm.entity.SysMenu;
import com.summer.boss.orm.dao.SysMenuMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.summer.boss.service.ISysRoleMenuService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统菜单表 服务实现类
 * </p>
 *
 * @author john.wang
 * @since 2021-07-15
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Resource
    private ISysRoleMenuService sysRoleMenuService;
    @Resource
    private MenuConvert menuConvert;

    @Override
    public List<SysMenu> getMenus(List<Integer> roleIds, boolean roleRequired) {
        // 角色必传的情况下，如果没有传直接返回空集合
        if (roleRequired && CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        // 传了角色就根据角色过滤菜单
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<Integer> menuIds = this.sysRoleMenuService.getMenuIds(roleIds);
            if (CollectionUtils.isEmpty(menuIds)) {
                return Collections.emptyList();
            }

            return this.list(new LambdaQueryWrapper<SysMenu>().in(SysMenu::getId, menuIds));
        }
        // 返回所有菜单
        return this.list();
    }

    @Override
    public List<MenuTreeVO> getMenuTree() {
        List<SysMenu> sysMenus =  this.list(new LambdaQueryWrapper<SysMenu>().in(SysMenu::getType, Lists.newArrayList(MenuTypeEnum.DIR, MenuTypeEnum.MENU)));

        List<SysMenu> level1 = sysMenus.stream().filter(f -> MenuTypeEnum.DIR.equals(f.getType())).sorted(Comparator.comparing(SysMenu::getOrder)).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(level1)) {
            return Collections.emptyList();
        }

        List<MenuTreeVO> menuTrees = this.menuConvert.po2TreeVo(level1);

        menuTrees.forEach(f -> {
            this.wrapChildren(f, sysMenus);
        });

        return menuTrees;
    }

    private void wrapChildren(MenuTreeVO menuTree, List<SysMenu> allMenus) {
        List<SysMenu> sysMenus = allMenus.stream().filter(c -> menuTree.getId().equals(c.getPId())).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(sysMenus)) {
            return;
        }

        List<MenuTreeVO> children = this.menuConvert.po2TreeVo(sysMenus);

        children.forEach(c -> {this.wrapChildren(c, allMenus);});

        menuTree.setChildren(children);
    }
}
